import 'package:flutter/material.dart';
import 'package:flutter/services.dart' show TextInputFormatter;
import '../button/gkb_button.dart' show GKBTextButton;

class InputEditWidget extends StatefulWidget {
  final String? labelText;
  final String? hintText;
  final String? errorText;
  final TextInputType? keyboardType;
  final VoidCallback? onEditingComplete;
  final FocusNode? focusNode;
  final FormFieldValidator<String>? validator;
  final bool isObscureText;

  final Function(String value)? textChange;
  final bool isOutLine;
  final EdgeInsets? contentPadding;
  final bool autofocus;
  final bool enabled;
  final Color? backgroundColor;
  final double radius;
  final Color? borderColor;
  final int maxLines;
  final int minLines;
  final int? maxLength;
  final CrossAxisAlignment suffixAlignment;
  final Widget? suffixIcon;
  final TextStyle? textStyle;
  final TextStyle? hintStyle;
  final TextStyle? labelStyle;
  final TextStyle? prefixStyle;
  final TextStyle? countStyle;
  final Widget? prefixIcon;
  final String? prefixText;
  final Function(String text)? onFieldSubmitted;

  ///提交按钮显示的文字（统计字数的时候）
  final String submitText;
  final bool needClear;

  final List<TextInputFormatter>? inputFormatters;
  final TextEditingController? controller;
  final void Function(String value)? onSubmit;
  final TextAlign textAlign;
  final bool isDense;
  final BoxConstraints? prefixIconConstraints;

  const InputEditWidget(
      {Key? key,
      this.hintText,
      this.labelText,
      this.errorText,
      this.keyboardType,
      this.onEditingComplete,
      this.focusNode,
      this.isObscureText = false,
      this.prefixText,
      // this.validator,
      // this.validatorText = '',
      this.validator,
      this.onFieldSubmitted,
      this.textAlign = TextAlign.start,
      this.isOutLine = false,
      this.enabled = true,
      this.contentPadding,
      this.suffixIcon,
      this.inputFormatters,
      this.autofocus = false,
      this.isDense = false,
      this.needClear = true,
      this.backgroundColor,
      this.radius = 0,
      this.borderColor,
      this.maxLines = 1,
      this.minLines = 1,
      this.maxLength,
      this.prefixIconConstraints,
      this.suffixAlignment = CrossAxisAlignment.center,
      this.onSubmit,
      required this.textChange,
      this.textStyle,
      this.hintStyle,
      this.labelStyle,
      this.prefixStyle,
      this.countStyle,
      this.controller,
      this.prefixIcon,
      this.submitText = 'Submit'})
      : super(key: key);

  @override
  _InputEditWidgetState createState() => _InputEditWidgetState();
}

class _InputEditWidgetState extends State<InputEditWidget> {
  late TextEditingController _controller;
  bool isObscureText = false;

  final Color _hintColor = const Color(0xffc7c8c7);
  final Color _errorColor = const Color(0xfff15e5e);
  final Color _lineColor = const Color(0xffe3e3e5);
  final Color _eyesColor = const Color(0xffcecece);

  @override
  void initState() {
    super.initState();
    _controller = widget.controller ?? TextEditingController();
    _controller.addListener(initListener);

    isObscureText = widget.isObscureText;
  }

  @override
  void didUpdateWidget(covariant InputEditWidget oldWidget) {
    super.didUpdateWidget(oldWidget);
    isObscureText = widget.isObscureText;
  }

  void initListener() {
    setState(() {
      widget.textChange?.call(_controller.text);
    });
  }

  @override
  void dispose() {
    super.dispose();
    _controller.removeListener(initListener);
  }

  @override
  Widget build(BuildContext context) {
    return TextFormField(
        enabled: widget.enabled,
        maxLength: widget.maxLength,
        minLines: widget.minLines,
        controller: _controller,
        maxLines: widget.maxLines,
        textAlign: widget.textAlign,
        keyboardType: widget.keyboardType,
        inputFormatters: widget.inputFormatters,
        onEditingComplete: widget.onEditingComplete,
        focusNode: widget.focusNode,
        textInputAction: TextInputAction.done,
        obscureText: isObscureText,
        onFieldSubmitted: (value) {
          widget.onFieldSubmitted?.call(value);
        },
        style: widget.textStyle ??
            const TextStyle(
              fontSize: 13,
              color: Color(0xff222222),
            ),
        autovalidateMode: AutovalidateMode.onUserInteraction,
        validator: widget.validator,
        autofocus: widget.autofocus,

        ///基于有maxLength的时候  TextFormField会显示字数统计，此处处理了
        ///三种情况如下
        ///1.字数统计在左，Submit提交在右 --- counterBuilder
        ///2.只有字数统计在右 buildCounter为null时，maxLength有值会用采用系统默认的样式，在右下角显示字数统计
        ///3.什么都不显示 无需字数统计需要传noneCounterBuilder
        buildCounter: widget.onSubmit != null
            ? _counterBuilder
            : widget.maxLines > 1
                ? null
                : _noneBuilder,
        decoration: _decoration);
  }

  InputDecoration get _decoration {
    return InputDecoration(
        hintText: widget.hintText,
        alignLabelWithHint: true,
        errorMaxLines: 3,
        filled: true,
        isDense: widget.isDense,
        fillColor: widget.backgroundColor ?? Colors.transparent,
        contentPadding: widget.contentPadding ?? EdgeInsets.zero,
        errorText: widget.errorText,
        labelText: widget.labelText,
        labelStyle: widget.labelStyle ??
            TextStyle(
              color: _hintColor,
              fontSize: 13,
            ),
        hintStyle: widget.hintStyle ??
            TextStyle(
              fontSize: 13,
              color: _hintColor,
            ),
        errorStyle: TextStyle(
          fontSize: 11,
          color: _errorColor,
        ),
        enabledBorder: _border,
        focusedBorder: _border,
        focusedErrorBorder: _border,
        errorBorder: _border,
        disabledBorder: _border,
        border: _border,
        suffixIconConstraints: const BoxConstraints(minWidth: 0),
        prefixIcon: widget.prefixIcon,
        prefixText: widget.prefixText,
        prefixStyle: widget.prefixStyle,
        prefixIconConstraints: widget.prefixIconConstraints ??
            const BoxConstraints(
              maxWidth: 100,
            ),
        suffixIcon: widget.suffixIcon ?? _suffixIcon);
  }

  InputBorder get _border {
    if (widget.isOutLine) {
      return OutlineInputBorder(
        borderRadius: BorderRadius.circular(widget.radius),
        borderSide: BorderSide(
          color: widget.borderColor ?? _lineColor,
          width: 0.5,
        ),
      );
    }
    return UnderlineInputBorder(
      borderSide: BorderSide(
        color: _lineColor,
        width: 0.5,
      ),
    );
  }

  Widget? get _suffixIcon {
    return Row(
      mainAxisAlignment: MainAxisAlignment.end,
      mainAxisSize: MainAxisSize.min,
      crossAxisAlignment: widget.suffixAlignment,
      children: [
        _obscureButton,
        _clearButton,
      ],
    );
  }

  Widget? _noneBuilder(BuildContext context,
      {required int currentLength,
      required bool isFocused,
      required int? maxLength}) {
    //隐藏字数统计
    return null;
  }

  Widget? _counterBuilder(BuildContext context,
      {required int currentLength,
      required bool isFocused,
      required int? maxLength}) {
    if (maxLength == null || maxLength == 0) {
      return null;
    }
    return Container(
      width: double.infinity,
      margin: EdgeInsets.zero,
      padding: const EdgeInsets.only(bottom: 10),
      //color: Colors.black12,
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: [
          Text(
            '$currentLength/$maxLength',
            style: widget.countStyle ??
                const TextStyle(fontSize: 12, color: Color(0xff999999)),
          ),
          submitBtn(enable: currentLength != 0)
        ],
      ),
    );
  }

  Widget submitBtn({bool enable = false}) {
    return GKBTextButton(
      onTap: enable
          ? () {
              widget.onSubmit?.call(_controller.text);
            }
          : null,
      title: widget.submitText,
      size: Size.zero,
      titleSize: 12,
      padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 4),
      radius: 4,
    );
  }

  Widget get _obscureButton {
    if (widget.isObscureText) {
      return Container(
        width: 20,
        alignment: Alignment.centerRight,
        margin: EdgeInsets.only(right: 5),
        child: IconButton(
            iconSize: 18.0,
            padding: EdgeInsets.zero,
            icon: Icon(isObscureText ? Icons.visibility_off : Icons.visibility,
                color: _eyesColor),
            onPressed: () => setState(() {
                  isObscureText = !isObscureText;
                })),
      );
    }
    return const SizedBox();
  }

  Widget get _clearButton {
    if (_controller.text.isNotEmpty && widget.needClear) {
      return Container(
        width: 20,
        alignment: Alignment.topCenter,
        margin: EdgeInsets.only(right: 10),
        child: IconButton(
            padding: EdgeInsets.zero,
            onPressed: () {
              _controller.clear();
            },
            icon: Icon(
              Icons.cancel,
              size: 18,
              color: _eyesColor,
            )),
      );
    }
    return const SizedBox();
  }
}
